#include "CopperParticleDevice.h"
#include <QDebug>
#include <QDateTime>
#include <QElapsedTimer>
#include <QCoreApplication>
#include <QRegularExpression>
#include <QThread>
#include <QMutex>

CopperParticleDevice::CopperParticleDevice(QObject *parent)
    : QObject(parent)
    , m_socket(new QTcpSocket(this))
    , m_requestCheckTimer(new QTimer(this))
    , m_queueProcessTimer(new QTimer(this))
    , m_processingCommand(false)
{
    connect(m_socket, &QTcpSocket::connected, this, &CopperParticleDevice::onConnected);
    connect(m_socket, &QTcpSocket::disconnected, this, &CopperParticleDevice::onDisconnected);
    connect(m_socket, &QTcpSocket::readyRead, this, &CopperParticleDevice::onReadyRead);
    connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
            this, &CopperParticleDevice::onError);

    m_requestCheckTimer->setInterval(500);
    connect(m_requestCheckTimer, &QTimer::timeout, this, &CopperParticleDevice::checkPendingRequests);
    m_requestCheckTimer->start();

    // 队列处理定时器
    m_queueProcessTimer->setInterval(50);
    connect(m_queueProcessTimer, &QTimer::timeout, this, &CopperParticleDevice::processCommandQueue);
    m_queueProcessTimer->start();
}

CopperParticleDevice::~CopperParticleDevice()
{
    disconnectFromDevice();
}

bool CopperParticleDevice::connectToDevice(const QString &host, quint16 port)
{
    if (m_socket->state() == QAbstractSocket::ConnectedState) {
        disconnectFromDevice();
    }

    m_socket->connectToHost(host, port);
    return m_socket->waitForConnected(3000);
}

void CopperParticleDevice::disconnectFromDevice()
{
    clearCommandQueue();
    m_socket->disconnectFromHost();
    if (m_socket->state() != QAbstractSocket::UnconnectedState) {
        m_socket->waitForDisconnected(1000);
    }
    m_pendingRequests.clear();
}

bool CopperParticleDevice::isConnected() const
{
    return m_socket->state() == QAbstractSocket::ConnectedState;
}

bool CopperParticleDevice::sendDeviceCommand(DeviceProtocol::IPCCommand command,
                                             const QVariantMap &params)
{

    DeviceCommandTask task(command, params, CommandPriority::Normal);
    task.timestamp = QDateTime::currentMSecsSinceEpoch();

    addCommandToQueue(task);
    return true;
}

void CopperParticleDevice::addImmediateCommand(DeviceProtocol::IPCCommand command,
                                               const QVariantMap &params)
{

    DeviceCommandTask task(command, params, CommandPriority::Immediate);
    task.timestamp = QDateTime::currentMSecsSinceEpoch();
    addCommandToQueue(task);
}

void CopperParticleDevice::addCommandToQueue(const DeviceCommandTask &task)
{
    switch (task.priority) {
    case CommandPriority::Normal: {
        QMutexLocker locker(&m_normalQueueMutex);
        m_normalQueue.enqueue(task);
        qDebug() << "普通命令加入队列，当前普通队列大小:" << m_normalQueue.size();
        break;
    }
    case CommandPriority::High: {
        QMutexLocker locker(&m_highPriorityMutex);
        m_highPriorityQueue.enqueue(task);
        qDebug() << "高优先级命令加入队列，当前高优先级队列大小:" << m_highPriorityQueue.size();
        break;
    }
    case CommandPriority::Immediate:
        // 立即执行命令
        sendImmediateCommand(task);
        break;
    }
}

bool CopperParticleDevice::sendImmediateCommand(const DeviceCommandTask &task)
{
    if (!isConnected()) {
        qDebug() << "设备未连接，无法发送立即命令";
        return false;
    }

    QString qn;
    QByteArray packet = buildCommandPacket(task.command, task.params, qn);
    if (packet.isEmpty()) {
        qDebug() << "构建立即命令包失败";
        return false;
    }

    qint64 bytesWritten = m_socket->write(packet);
    if (bytesWritten == -1) {
        qDebug() << "发送立即命令失败:" << m_socket->errorString();
        return false;
    }

    if (!m_socket->waitForBytesWritten(1000)) {
        qDebug() << "立即命令写入超时";
        return false;
    }

    qDebug() << "立即命令发送成功:" << static_cast<int>(task.command) << "QN:" << qn;
    return true;
}

void CopperParticleDevice::processCommandQueue()
{
    if (m_processingCommand) {
        return;
    }

    DeviceCommandTask nextTask;
    bool hasTask = false;

    // 优先检查高优先级队列
    {
        QMutexLocker locker(&m_highPriorityMutex);
        if (!m_highPriorityQueue.isEmpty()) {
            nextTask = m_highPriorityQueue.dequeue();
            hasTask = true;
            qDebug() << "处理高优先级命令，剩余高优先级队列:" << m_highPriorityQueue.size();
        }
    }

    // 如果没有高优先级任务，检查普通队列
    if (!hasTask) {
        QMutexLocker locker(&m_normalQueueMutex);
        if (!m_normalQueue.isEmpty()) {
            nextTask = m_normalQueue.dequeue();
            hasTask = true;
            qDebug() << "处理普通命令，剩余普通队列:" << m_normalQueue.size();
        }
    }

    if (!hasTask) {
        return;
    }

    m_processingCommand = true;
    m_currentTask = nextTask;

    // 如果是立即命令，直接发送并完成
    if (m_currentTask.priority == CommandPriority::Immediate) {
        bool success = sendImmediateCommand(m_currentTask);
        completeCurrentCommand(success);
        return;
    }

    qDebug() << "开始处理队列命令:" << static_cast<int>(m_currentTask.command)
             << "优先级:" << static_cast<int>(m_currentTask.priority);

    // 构建并发送命令包
    QString qn;
    QByteArray packet = buildCommandPacket(m_currentTask.command, m_currentTask.params, qn);
    if (packet.isEmpty()) {
        qDebug() << "构建命令包失败，标记为完成";
        completeCurrentCommand(false);
        return;
    }

    m_currentTask.qn = qn;
    int cn = static_cast<int>(m_currentTask.command);

    // 设置待处理请求
    PendingRequest request;
    request.qn = qn;
    request.data = packet;
    request.command = m_currentTask.command;
    request.retryCount = 0;
    request.expireTime = QDateTime::currentMSecsSinceEpoch() + 3000;
    request.maxRetries = 3;
    request.hasQnRtn = false;
    request.hasExeRtn = false;
    request.completed = false;

    m_pendingRequests[qn] = request;

    if (!sendCommand(packet, cn)) {
        qDebug() << "发送命令失败";
        removePendingRequest(qn);
        completeCurrentCommand(false);
    } else {
        qDebug() << "命令发送成功，等待响应，QN:" << qn;
        // 设置超时检查
        QTimer::singleShot(5000, this, [this, qn]() {
            if (m_pendingRequests.contains(qn) && !m_pendingRequests[qn].completed) {
                qDebug() << "命令响应超时，QN:" << qn;
                retryCurrentCommand();
            }
        });
    }
}

void CopperParticleDevice::completeCurrentCommand(bool success, const QVariantMap &responseData)
{
    // 在重置 m_currentTask 之前保存命令类型
    DeviceProtocol::IPCCommand completedCommand = m_currentTask.command;

    // 发出命令完成信号，包含响应数据
    if (completedCommand != DeviceProtocol::IPCCommand::ReplyData) {
        // 使用 QMetaObject::invokeMethod 确保线程安全，并传递正确的命令类型
        QMetaObject::invokeMethod(this, [this, completedCommand, success, responseData]() {
            emit commandCompleted(completedCommand, success, responseData);
        }, Qt::QueuedConnection);

        qDebug() << "命令处理完成，命令:" << static_cast<int>(completedCommand) << "成功:" << success;
    }

    {
        QMutexLocker locker(&m_normalQueueMutex);
        m_processingCommand = false;
        m_currentTask = DeviceCommandTask();  // 重置当前任务
    }

    // 处理下一个命令
    QTimer::singleShot(10, this, &CopperParticleDevice::processCommandQueue);
}

void CopperParticleDevice::retryCurrentCommand()
{
    QMutexLocker locker(&m_normalQueueMutex);

    if (m_currentTask.retryCount < 3) {
        m_currentTask.retryCount++;
        qDebug() << "命令重试，次数:" << m_currentTask.retryCount;

        m_normalQueue.prepend(m_currentTask);
        m_processingCommand = false;
        m_currentTask = DeviceCommandTask();
    } else {
        qDebug() << "命令重试次数耗尽，标记为失败";
        completeCurrentCommand(false);
    }
}

int CopperParticleDevice::getQueueSize() const
{
    QMutexLocker locker1(&m_normalQueueMutex);
    QMutexLocker locker2(&m_highPriorityMutex);
    return m_normalQueue.size() + m_highPriorityQueue.size();
}

void CopperParticleDevice::clearCommandQueue()
{
    QMutexLocker locker1(&m_normalQueueMutex);
    QMutexLocker locker2(&m_highPriorityMutex);
    m_normalQueue.clear();
    m_highPriorityQueue.clear();
    m_processingCommand = false;
    qDebug() << "命令队列已清空";
}

QByteArray CopperParticleDevice::buildCommandPacket(DeviceProtocol::IPCCommand command,
                                                    const QVariantMap &params,
                                                    QString &qn)
{
    qn = generateQN();
    int flag = getCommandFlag(command);
    QMap<QString, QString> protocolParams = convertToProtocolParams(command, params);
    int cn = static_cast<int>(command);

    QByteArray packet = m_parser.buildPacket(qn, cn, flag, protocolParams);
    if (packet.isEmpty()) {
        qDebug() << "Failed to build packet for command:" << static_cast<int>(command);
    }

    return packet;
}

// 在 convertToProtocolParams 函数中
QMap<QString, QString> CopperParticleDevice::convertToProtocolParams(DeviceProtocol::IPCCommand command,
                                                                     const QVariantMap &params)
{
    QMap<QString, QString> protocolParams;

    switch (command) {
    case DeviceProtocol::IPCCommand::ReplyData:
        // 数据应答命令 - 直接传递所有参数
        for (auto it = params.begin(); it != params.end(); ++it) {
            protocolParams[it.key()] = it.value().toString();
        }
        break;
    case DeviceProtocol::IPCCommand::SetupRecipe:
        // 直接使用协议字段名，不进行转换
        if (params.contains("D"))
            protocolParams["D"] = QString::number(params["D"].toDouble(), 'f', 3);
        if (params.contains("R"))
            protocolParams["R"] = QString::number(params["R"].toDouble(), 'f', 3);
        if (params.contains("S"))
            protocolParams["S"] = QString::number(params["S"].toDouble(), 'f', 3);
        if (params.contains("H"))
            protocolParams["H"] = QString::number(params["H"].toDouble(), 'f', 3);
        if (params.contains("V"))
            protocolParams["V"] = QString::number(params["V"].toDouble(), 'f', 3);
        if (params.contains("FV"))
            protocolParams["FV"] = QString::number(params["FV"].toDouble(), 'f', 3);
        break;

    case DeviceProtocol::IPCCommand::FastMotion:
    case DeviceProtocol::IPCCommand::FastCutting:
        // 坐标参数 - 直接使用协议字段名
        if (params.contains("SX"))
            protocolParams["SX"] = QString::number(params["SX"].toDouble(), 'f', 3);
        if (params.contains("SY"))
            protocolParams["SY"] = QString::number(params["SY"].toDouble(), 'f', 3);
        if (params.contains("SZ"))
            protocolParams["SZ"] = QString::number(params["SZ"].toDouble(), 'f', 3);
        if (params.contains("EX"))
            protocolParams["EX"] = QString::number(params["EX"].toDouble(), 'f', 3);
        if (params.contains("EY"))
            protocolParams["EY"] = QString::number(params["EY"].toDouble(), 'f', 3);
        if (params.contains("EZ"))
            protocolParams["EZ"] = QString::number(params["EZ"].toDouble(), 'f', 3);

        // 必需参数
        if (params.contains("NO")) {
            protocolParams["NO"] = QString::number(params["NO"].toInt());
        } else {
            protocolParams["NO"] = "0";
        }

        if (params.contains("Count")) {
            protocolParams["Count"] = QString::number(params["Count"].toInt());
        } else {
            protocolParams["Count"] = "1";
        }

        // 切割特有的参数
        if (command == DeviceProtocol::IPCCommand::FastCutting) {
            if (params.contains("V"))
                protocolParams["V"] = QString::number(params["V"].toDouble(), 'f', 3);
            if (params.contains("R"))
                protocolParams["R"] = QString::number(params["R"].toDouble(), 'f', 3);
        }
        break;

    case DeviceProtocol::IPCCommand::SetDO:
    case DeviceProtocol::IPCCommand::ResetDO:
        if (params.contains("IOBits"))
            protocolParams["IOBits"] = params["IOBits"].toString();
        break;

    case DeviceProtocol::IPCCommand::RemoveAction:
        if (params.contains("NO"))
            protocolParams["NO"] = QString::number(params["NO"].toInt());
        break;

    case DeviceProtocol::IPCCommand::QueryDIList:
        if (params.contains("IOBits"))
            protocolParams["IOBits"] = params["IOBits"].toString();
        break;
    case DeviceProtocol::IPCCommand::SpindleStart:
        if (params.contains("R"))
            protocolParams["R"] = QString::number(params["R"].toDouble(), 'f', 3);
        break;
    default:
        // 默认情况下，直接传递所有参数
        for (auto it = params.begin(); it != params.end(); ++it) {
            protocolParams[it.key()] = it.value().toString();
        }
        break;
    }

    return protocolParams;
}

bool CopperParticleDevice::processCommandResponse(DeviceProtocol::IPCCommand command,
                                                  const QMap<QString, QString> &responseParams,
                                                  QVariantMap *output)
{
    qDebug() << "处理命令响应 - 命令:" << static_cast<int>(command);
    qDebug() << "响应参数:" << responseParams;

    if (output) {
        switch (command) {
        case DeviceProtocol::IPCCommand::QueryRecipe:
            // 直接使用协议字段名，不进行转换
            if (responseParams.contains("D"))
                (*output)["D"] = responseParams["D"].toDouble();
            if (responseParams.contains("R"))
                (*output)["R"] = responseParams["R"].toDouble();
            if (responseParams.contains("S"))
                (*output)["S"] = responseParams["S"].toDouble();
            if (responseParams.contains("H"))
                (*output)["H"] = responseParams["H"].toDouble();
            if (responseParams.contains("V"))
                (*output)["V"] = responseParams["V"].toDouble();
            return true;

        case DeviceProtocol::IPCCommand::QueryState:
            if (responseParams.contains("State")) {
                QString stateStr = responseParams["State"];
                // 检查是否为 FL%3.142%5.142%4.142%31.1 格式
                if (stateStr.contains('%')) {
                    // 解析扩展状态数据格式
                    parseExtendedStateData(stateStr, output);
                } else {
                    // 原有的简单状态解析
                    if (stateStr.length() >= 2) {
                        (*output)["state"] = stateStr.left(1);
                        (*output)["controlMode"] = stateStr.mid(1, 1);
                    }
                }
            }
            return true;

        case DeviceProtocol::IPCCommand::QueryDIList:
            if (responseParams.contains("IOBits")) {
                (*output)["IOBits"] = responseParams["IOBits"];
            }
            return true;

        default:
            // 其他命令直接传递所有参数
            for (auto it = responseParams.begin(); it != responseParams.end(); ++it) {
                (*output)[it.key()] = it.value();
            }
            return true;
        }
    }

    return false;
}

int CopperParticleDevice::getCommandFlag(DeviceProtocol::IPCCommand command)
{
    switch (command) {
    case DeviceProtocol::IPCCommand::DeviceInitialize:
    case DeviceProtocol::IPCCommand::QueryRecipe:
    case DeviceProtocol::IPCCommand::QueryState:
    case DeviceProtocol::IPCCommand::QueryDIList:
    case DeviceProtocol::IPCCommand::QueryActionChecksum:
    case DeviceProtocol::IPCCommand::RemoveAction:
        return 1;

    case DeviceProtocol::IPCCommand::FastMotion:
    case DeviceProtocol::IPCCommand::FastCutting:
    case DeviceProtocol::IPCCommand::SetDO:
    case DeviceProtocol::IPCCommand::ResetDO:
    case DeviceProtocol::IPCCommand::AppendSetDO:
    case DeviceProtocol::IPCCommand::AppendResetDO:
    case DeviceProtocol::IPCCommand::Execute:
    case DeviceProtocol::IPCCommand::Stop:
    case DeviceProtocol::IPCCommand::Pause:
    case DeviceProtocol::IPCCommand::ClampAllFixture:
    case DeviceProtocol::IPCCommand::ReleaseAllFixture:
    case DeviceProtocol::IPCCommand::SpindleStart:
    case DeviceProtocol::IPCCommand::SpindleStop:
        return 0;

    default:
        return 1;
    }
}

void CopperParticleDevice::onConnected()
{
    emit connected();
}

void CopperParticleDevice::onDisconnected()
{
    emit disconnected();
}

void CopperParticleDevice::onReadyRead()
{
    QByteArray data = m_socket->readAll();
    m_buffer.append(data);
    cleanupPacketCache();

    while (true) {
        int headerPos = m_buffer.indexOf("##");
        if (headerPos == -1) {
            m_buffer.clear();
            break;
        }

        if (headerPos > 0) {
            m_buffer = m_buffer.mid(headerPos);
        }

        if (m_buffer.length() < 6) {
            break;
        }

        bool ok;
        int dataLength = m_buffer.mid(2, 4).toInt(&ok);
        if (!ok || dataLength < 0 || dataLength > 1024) {
            m_buffer = m_buffer.mid(2);
            continue;
        }

        int totalPacketLength = 2 + 4 + dataLength + 4 + 2;

        if (m_buffer.length() < totalPacketLength) {
            break;
        }

        QByteArray completePacket = m_buffer.left(totalPacketLength);
        m_buffer = m_buffer.mid(totalPacketLength);
        processSinglePacket(completePacket);
    }
}

void CopperParticleDevice::processSinglePacket(const QByteArray &packet)
{
    QByteArray dataSegment;
    if (m_parser.parsePacket(packet, dataSegment)) {
        QString qn;
        int cn, flag;
        QMap<QString, QString> params;

        if (m_parser.parseDataSegment(dataSegment, qn, cn, flag, params)) {
            qDebug() << "=== 解析数据包 ===";
            qDebug() << "QN:" << qn << "CN:" << cn << "Flag:" << flag;
            qDebug() << "参数:" << params;

            // 处理数据响应包，需要发送数据应答
            if (cn == 111 || cn == 201 || cn == 205 || cn == 206 ||
                cn == 210 || cn == 211 || cn == 212 || cn == 213) {
                qDebug() << "收到数据响应包，需要发送数据应答 CN=" << cn;
                QString noValue;
                if (params.contains("NO")) {
                    noValue = params["NO"];
                    qDebug() << "提取到NO参数:" << noValue;
                }

                // 立即发送数据应答（高优先级），使用相同的QN
                bool ackSent = sendDataAck(qn, cn, noValue);
                if (ackSent) {
                    qDebug() << "数据应答已发送，使用相同QN:" << qn;
                } else {
                    qDebug() << "数据应答发送失败";
                }

                // 对于查询命令，直接发送数据信号，不等待执行结果
                DeviceProtocol::IPCCommand queryCommand = static_cast<DeviceProtocol::IPCCommand>(cn);
                QVariantMap queryData;
                if (processCommandResponse(queryCommand, params, &queryData) && !queryData.isEmpty()) {
                    qDebug() << "直接发送查询数据信号 - 命令:" << static_cast<int>(queryCommand) << "数据:" << queryData;
                    emit queryDataReceived(queryCommand, queryData);
                }
            }

            // 原有的待处理请求逻辑保持不变（用于命令完成回调）
            if (m_pendingRequests.contains(qn)) {
                PendingRequest &request = m_pendingRequests[qn];
                bool shouldComplete = false;
                QVariantMap responseData;
                DeviceProtocol::IPCCommand requestCommand = request.command;

                switch (cn) {
                case 901: // 请求应答 (QnRtn)
                    qDebug() << "收到请求应答 (CN=901)";
                    if (params.contains("QnRtn")) {
                        request.hasQnRtn = true;
                        int qnRtn = params["QnRtn"].toInt();
                        qDebug() << "QnRtn值:" << qnRtn;

                        if (qnRtn != 1) {
                            request.completed = true;
                            responseData["error"] = QString("请求被拒绝, QnRtn: %1").arg(qnRtn);
                            shouldComplete = true;
                        }
                    }
                    break;

                case 902: // 执行结果 (ExeRtn)
                    qDebug() << "收到执行结果 (CN=902)";
                    if (params.contains("ExeRtn")) {
                        request.hasExeRtn = true;
                        int exeRtn = params["ExeRtn"].toInt();
                        qDebug() << "ExeRtn值:" << exeRtn;

                        responseData["exeRtn"] = exeRtn;
                        responseData["exeRtnMessage"] = getExeRtnErrorMessage(exeRtn);
                        responseData["success"] = (exeRtn == 1);

                        // 执行命令完成
                        request.completed = true;
                        shouldComplete = true;
                        qDebug() << "命令执行完成，执行结果:" << exeRtn;
                    }
                    break;

                default:
                    // 数据响应 - 对于查询命令，我们已经在上面的新机制中处理了
                    // 这里只更新状态，不触发完成
                    if (getCommandFlag(requestCommand) == 1) { // 查询命令
                        request.hasDataResponse = true;
                        qDebug() << "查询命令收到数据响应，等待执行结果完成信号";
                    }
                    break;
                }

                // 检查是否需要完成当前任务
                if (shouldComplete && m_processingCommand && m_currentTask.qn == qn) {
                    removePendingRequest(qn);
                    completeCurrentCommand(true, responseData);
                }
            }

            // 处理通知类型的消息（设备主动上报）
            if (cn == 201 && !m_pendingRequests.contains(qn)) {
                qDebug() << "收到设备状态通知";
                sendDataAck(qn, cn);

                // 处理状态通知数据
                QVariantMap output;
                if (processCommandResponse(static_cast<DeviceProtocol::IPCCommand>(cn), params, &output)) {
                    emit statusNotificationReceived(output);
                }
            }
        }
    }
}

QString CopperParticleDevice::getExeRtnErrorMessage(int exeRtn)
{
    switch (exeRtn) {
    case 1: return "成功";
    case 2: return "未知错误";
    case 3: return "无效请求（命令执行被拒绝：条件错误）";
    case 4: return "超时（通信超时，请稍后重试）";
    case 5: return "系统繁忙（系统当前繁忙，请稍候或稍后重试）";
    case 6: return "系统崩溃（系统当前不可用，请稍后重试）";
    case 100: return "数据未找到（该查询无可用数据）";
    default: return QString("未知执行结果代码: %1").arg(exeRtn);
    }
}

bool CopperParticleDevice::isDuplicatePacket(const QByteArray &packet)
{
    QString qn = extractQNFromPacket(packet);
    QString crc = extractCRCFromPacket(packet);

    if (qn.isEmpty() || crc.isEmpty()) {
        return false;
    }

    for (const PacketCache &cache : m_packetCache) {
        if (cache.qn == qn && cache.crc == crc) {
            return true;
        }
    }

    if (m_pendingRequests.contains(qn)) {
        return false;
    }

    PacketCache newCache;
    newCache.qn = qn;
    newCache.crc = crc;
    newCache.timestamp = QDateTime::currentMSecsSinceEpoch();
    m_packetCache.append(newCache);
    return false;
}

void CopperParticleDevice::cleanupPacketCache()
{
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    qint64 expireTime = currentTime - 10000;

    auto it = m_packetCache.begin();
    while (it != m_packetCache.end()) {
        if (it->timestamp < expireTime) {
            it = m_packetCache.erase(it);
        } else {
            ++it;
        }
    }

    if (m_packetCache.size() > 100) {
        std::sort(m_packetCache.begin(), m_packetCache.end(),
                  [](const PacketCache &a, const PacketCache &b) {
                      return a.timestamp < b.timestamp;
                  });

        while (m_packetCache.size() > 100) {
            m_packetCache.removeFirst();
        }
    }
}

bool CopperParticleDevice::sendDataAck(const QString &qn, int dataCn, const QString &no)
{
    if (!isConnected()) {
        qDebug() << "设备未连接，无法发送数据应答";
        return false;
    }

    QMap<QString, QString> ackParams;
    ackParams["DA"] = QString::number(dataCn); // 确保包含 DA 字段

    if (!no.isEmpty()) {
        ackParams["NO"] = no;
    }

    // 直接构建数据应答包，不经过参数转换
    QString ackQn = qn;
    int flag = 0; // 数据应答的 Flag 通常为 0
    int cn = 904; // 数据应答的 CN 固定为 904

    QByteArray ackPacket = m_parser.buildPacket(ackQn, cn, flag, ackParams);
    if (ackPacket.isEmpty()) {
        qDebug() << "构建数据应答包失败";
        return false;
    }

    // 立即发送数据应答
    qint64 bytesWritten = m_socket->write(ackPacket);
    if (bytesWritten == -1) {
        qDebug() << "发送数据应答失败:" << m_socket->errorString();
        return false;
    }

    if (!m_socket->waitForBytesWritten(1000)) {
        qDebug() << "数据应答写入超时";
        return false;
    }

    qDebug() << "数据应答发送成功: QN=" << qn << "DA=" << dataCn << "NO=" << no;
    return true;
}

QVariantMap CopperParticleDevice::waitForResponseData(const QString &qn, int timeout)
{
    if (!m_pendingRequests.contains(qn)) {
        emit errorOccurred("No pending request for QN: " + qn);
        return QVariantMap();
    }

    QElapsedTimer timer;
    timer.start();

    while (timer.elapsed() < timeout) {
        if (m_pendingRequests.contains(qn)) {
            PendingRequest &request = m_pendingRequests[qn];

            // 检查请求是否完成
            if (request.completed) {
                QVariantMap responseData = request.responseData;
                m_pendingRequests.remove(qn);
                return responseData;
            }
        }
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }

    // 超时处理
    removePendingRequest(qn);
    emit errorOccurred("Response timeout for QN: " + qn);
    return QVariantMap();
}

QString CopperParticleDevice::extractCRCFromPacket(const QByteArray &packet)
{
    if (packet.length() < 12) {
        return QString();
    }

    bool ok;
    int dataLength = packet.mid(2, 4).toInt(&ok);
    if (!ok || dataLength <= 0) {
        return QString();
    }

    int crcPos = 6 + dataLength;
    if (crcPos + 4 > packet.length()) {
        return QString();
    }

    return QString::fromUtf8(packet.mid(crcPos, 4));
}

QString CopperParticleDevice::extractQNFromPacket(const QByteArray &packet)
{
    if (packet.length() < 12) {
        return QString();
    }

    bool ok;
    int dataLength = packet.mid(2, 4).toInt(&ok);
    if (!ok || dataLength <= 0) {
        return QString();
    }

    QByteArray dataSegment = packet.mid(6, dataLength);
    QString dataStr = QString::fromUtf8(dataSegment);

    QRegularExpression qnRegex("QN=([^;]+)");
    QRegularExpressionMatch match = qnRegex.match(dataStr);

    if (match.hasMatch()) {
        return match.captured(1);
    }

    return QString();
}

void CopperParticleDevice::onError(QAbstractSocket::SocketError error)
{
    Q_UNUSED(error)
    emit errorOccurred(m_socket->errorString());
}

void CopperParticleDevice::checkPendingRequests()
{
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();

    auto it = m_pendingRequests.begin();
    while (it != m_pendingRequests.end()) {
        PendingRequest &request = it.value();

        if (currentTime >= request.expireTime) {
            if (request.retryCount < request.maxRetries) {
                request.retryCount++;
                request.expireTime = currentTime + 3000;
                resendRequest(request.qn);
                ++it;
            } else {
                emit errorOccurred("Command timeout for QN: " + request.qn);
                it = m_pendingRequests.erase(it);
            }
        } else {
            ++it;
        }
    }
}

void CopperParticleDevice::resendRequest(const QString &qn)
{
    if (m_pendingRequests.contains(qn)) {
        PendingRequest &request = m_pendingRequests[qn];
        qint64 bytesWritten = m_socket->write(request.data);
        if (bytesWritten == -1) {
            emit errorOccurred("Failed to resend command: " + m_socket->errorString());
            m_pendingRequests.remove(qn);
        } else {
            m_socket->waitForBytesWritten(3000);
        }
    }
}

void CopperParticleDevice::removePendingRequest(const QString &qn)
{
    m_pendingRequests.remove(qn);
}

bool CopperParticleDevice::sendCommand(const QByteArray &command, int cn, bool needResponse)
{
    if (!isConnected()) {
        emit errorOccurred("Device not connected");
        return false;
    }

    if (command.isEmpty()) {
        emit errorOccurred("Empty command");
        return false;
    }

    QString qn;
    if (needResponse) {
        QByteArray dataSegment;
        if (m_parser.parsePacket(command, dataSegment)) {
            QMap<QString, QString> params;
            int parsedCn, flag;
            if (m_parser.parseDataSegment(dataSegment, qn, parsedCn, flag, params)) {
                PendingRequest request;
                request.qn = qn;
                request.data = command;
                request.retryCount = 0;
                request.expireTime = QDateTime::currentMSecsSinceEpoch() + 3000;
                request.maxRetries = 3;
                m_pendingRequests[qn] = request;
            } else {
                emit errorOccurred("Failed to parse command for tracking");
                return false;
            }
        } else {
            emit errorOccurred("Failed to parse command packet");
            return false;
        }
    }

    qint64 bytesWritten = m_socket->write(command);
    if (bytesWritten == -1) {
        if (needResponse && !qn.isEmpty()) {
            removePendingRequest(qn);
        }
        emit errorOccurred("Failed to send command: " + m_socket->errorString());
        return false;
    }

    if (!m_socket->waitForBytesWritten(3000)) {
        if (needResponse && !qn.isEmpty()) {
            removePendingRequest(qn);
        }
        emit errorOccurred("Write timeout");
        return false;
    }

    return true;
}

QByteArray CopperParticleDevice::waitForResponse(const QString &qn, int timeout)
{
    if (!m_pendingRequests.contains(qn)) {
        emit errorOccurred("No pending request for QN: " + qn);
        return QByteArray();
    }

    QElapsedTimer timer;
    timer.start();

    while (timer.elapsed() < timeout) {
        if (m_pendingRequests.contains(qn)) {
            PendingRequest &request = m_pendingRequests[qn];

            // 检查请求是否完成
            if (request.completed) {
                QByteArray response;
                // 可以返回处理后的数据或其他标识
                m_pendingRequests.remove(qn);
                qDebug() << "请求完成，QN:" << qn;
                return response; // 或者返回其他有意义的数据
            }
        }
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }

    // 超时处理
    removePendingRequest(qn);
    emit errorOccurred("Response timeout for QN: " + qn);
    return QByteArray();
}

QString CopperParticleDevice::generateQN()
{
    static QMutex mutex;
    static qint64 lastTimestamp = 0;
    static int sequence = 0;

    QMutexLocker locker(&mutex);

    QDateTime now = QDateTime::currentDateTime();
    qint64 currentTimestamp = now.toMSecsSinceEpoch();

    // 如果时间戳相同，使用序列号
    if (currentTimestamp == lastTimestamp) {
        sequence++;
        // 序列号超过999时等待到下一毫秒
        if (sequence > 999) {
            // 等待1毫秒
            QThread::usleep(1000);
            now = QDateTime::currentDateTime();
            currentTimestamp = now.toMSecsSinceEpoch();
            sequence = 0;
        }
    } else {
        sequence = 0;
        lastTimestamp = currentTimestamp;
    }

    // 标准17位格式：yyyyMMddhhmmsszzz
    QString baseQN = now.toString("yyyyMMddhhmmsszzz");

    // 如果使用了序列号，替换最后3位
    if (sequence > 0) {
        baseQN = baseQN.left(14) + QString("%1").arg(sequence, 3, 10, QLatin1Char('0'));
    }

    return baseQN;
}

// 新增的扩展状态数据解析函数
bool CopperParticleDevice::parseExtendedStateData(const QString& stateStr, QVariantMap* output)
{
    if (!output) return false;

    // 按 % 分割字符串
    QStringList parts = stateStr.split("%");

    // 检查数据完整性：FL + 4个数据 = 5部分
    if (parts.size() != 5) {
        qDebug() << "扩展状态数据格式错误，期望5个部分，实际得到:" << parts.size();
        return false;
    }

    // 解析状态部分 (FL)
    QString stateCode = parts[0];
    if (stateCode.length() >= 2) {
        (*output)["state"] = stateCode.left(1);           // "F"
        (*output)["controlMode"] = stateCode.mid(1, 1);   // "L"
    } else {
        qDebug() << "状态代码长度不足";
        return false;
    }
    // 解析坐标和力矩数据
    bool ok1, ok2, ok3, ok4;
    (*output)["x"] = parts[1].toDouble(&ok1);
    (*output)["y"] = parts[2].toDouble(&ok2);
    (*output)["z"] = parts[3].toDouble(&ok3);
    (*output)["torque"] = parts[4].toDouble(&ok4);

    if (!ok1 || !ok2 || !ok3 || !ok4) {
        qDebug() << "数据转换失败:" << parts[1] << parts[2] << parts[3] << parts[4];
        return false;
    }
    return true;
}
